////////////////////////////////////////////////
// 封装混入请求方法封装，用于请求发送，赋值
// 吴野
// 2021-10-27 11:31:45
////////////////////////////////////////////////
var async = require("async");
export default {
    data() {
        return {
        }
    },
    created() {
        // 挂载api文件，以及方法
        if (this.apiConfig) {
            this['$api'] = this.$Api.get(this.apiConfig.api);
        }
    },
    mounted() {
        // 挂载api文件，以及方法
        if (this.apiConfig) {
            this['$api'] = this.$Api.get(this.apiConfig.api);
        }
    },
    methods: {
        /**
        * $render函数描述
        * @param {Object} option 配置参数对象
        * @param {String} num 数量规定取数据列表中固定数量数据，但一定是固定10条
        * @param {String} isPost 控制是否发送请求，true为发送，false为不发送。
        * @param {String} dataName 要赋值的属性值，data里的属性值与页面渲染的对象属性值一致。
        * @param {String} apiUrl 请求的方法名称。调用接口的方法名称。
        * @param {Object} parames 请求方法所要传递的参数值。
        * @param {Function} func 请求方法返回成功的回调函数，用于自定义返回数据。
        */
        $render(option) {
            if (option.isPost) {
                let postObj = [];
                if (!option.num) {
                    postObj = [option.parames, (res) => {
                        if (res.code !== 200 && res.code) {
                            this.$Message.error('请求失败！');
                            return
                        } else {
                            this[option.dataName] = res.data;
                            if (option.func) {
                                option.func(res);
                            }
                        }
                    }]
                } else {
                    postObj = [option.parames, option.num, (res) => {
                        if (res.code !== 200 && res.code) {
                            this.$Message.error('请求失败！');
                            return
                        } else {
                            this[option.dataName] = res.data;
                            if (option.func) {
                                option.func(res);
                            }
                        }
                    }]
                }
                this.$api[option.apiUrl](...postObj)
            }
        },
        /**
       * $async函数描述
       * @param {Object} option 配置参数对象
       * @param {String} isPost 控制是否发送请求，true为发送，false为不发送。
       * @param {String} dataName 要赋值的属性值，data里的属性值与页面渲染的对象属性值一致。
       * @param {String} apiUrl 请求的方法名称。调用接口的方法名称。
       * @param {Object} parames 请求方法所要传递的参数值。
       * @param {Function} cb 用于回调传递参数，(res)=>{res为回调接收取参数}
       */
        $async(option, cb) {
            let funcArray = [];
            for (const key in option) {
                if (option.hasOwnProperty.call(option, key)) {
                    const item = option[key];
                    funcArray.push(new Promise((resolve, reject) => {
                        this.$render(Object.assign({}, item, {
                            func: (returnData) => {
                                if (returnData.code !== 200) {
                                    reject('错误')
                                } else {
                                    let obj = {};
                                    obj[key] = returnData
                                    resolve(obj)
                                }
                            }
                        }))
                    }))
                }
            }
            this.$asyncAll(funcArray, (resData) => {
                cb(resData)
            });
        },
        async $asyncAll(array, cb) {
            let values = await Promise.all(array);
            cb(values)
        },
        /**
        * $asyncs函数描述：顺序执行函数，函数上一个请求结果为下一个方法的条件。如果在任何一个环节执行报错，
        * 则结束当前执行，将返回结果合并，以及错误信息。
        * @param {Object} option 方法配置项
        * @param {String} isPost 控制是否发送请求，true为发送，false为不发送。
        * @param {String} dataName 要赋值的属性值，data里的属性值与页面渲染的对象属性值一致。
        * @param {String} apiUrl 请求的方法名称。调用接口的方法名称。
        * @param {Object} parames 请求方法所要传递的参数值。
        * @param {String} isFirst 是否为首次执行，必须设置，否则无法执行下去。
        * @param {Array} transmit 传递下一个函数所需要的参数，从返回的结果集中取。注意：下一个函数所需要的条件，必须在data对象根内部，且属性名一致。
        */
        $asyncs(option, cb) {
            let funcArray = [];
            for (const key in option) {
                if (option.hasOwnProperty.call(option, key)) {
                    const item = option[key];
                    let funcs = item.isFirst ? (callback) => {
                        this.$render(Object.assign({}, item, {
                            func: (returnData) => {
                                if (returnData.code !== 200) {
                                    callback({ error: key + '错误！' }, returnData.data, {});
                                } else {
                                    let obj = {};
                                    if (item.transmit && item.transmit.length !== 0) {
                                        for (let i = 0; i < item.transmit.length; i++) {
                                            const element = item.transmit[i];
                                            // 注意，下一个函数所需要的条件，必须在data对象根内部，且属性名一致。
                                            obj[element] = returnData.data[element];
                                        }
                                    }
                                    let result = {}
                                    result[key] = returnData.data;
                                    callback(null, result, obj)
                                }
                            }
                        }))
                    } : (result, transmit, callback) => {
                        let cloneItem = null;
                        if (transmit) {
                            cloneItem = Object.assign({}, item.parames, transmit);
                        }
                        item.parames = cloneItem ? cloneItem : item.parames;
                        this.$render(Object.assign({}, item, {
                            func: (returnData) => {
                                if (returnData.code !== 200) {
                                    callback({ error: key + '错误！' }, returnData.data, {});
                                } else {
                                    let obj = {};
                                    if (item.transmit && item.transmit.length !== 0) {
                                        for (let i = 0; i < item.transmit.length; i++) {
                                            const element = item.transmit[i];
                                            // 注意，下一个函数所需要的条件，必须在data对象根内部，且属性名一致。
                                            obj[element] = returnData.data[element];
                                        }
                                    }
                                    result[key] = returnData.data;
                                    callback(null, result, obj)
                                }
                            }
                        }))
                    };
                    funcArray.push(funcs);
                    this.$asyncModule(funcArray, cb)
                }
            }
        },
        $asyncModule(funcArray, cb) {
            async.waterfall(funcArray, function (err, result) {
                cb(err, result);
                //执行的任务中方法回调err参数时，将被传递至本方法的err参数
                // 参数result为最后一个方法的回调结果'done'     
            })
        }
    }
}

// 使用案例
{/* <template>
    <div>
        <div class="i-layout-page-header">
            <PageHeader title="搜索列表（应用）" hidden-breadcrumb>
                <div slot="content" class="ivu-mt ivu-mb" style="max-width: 500px;margin: 0 auto;">
                    <Input search size="large" enter-button="搜索" placeholder="Enter something..." />
                </div>
            </PageHeader>
        </div>
        <Card :bordered="false" dis-hover class="ivu-mt">
            <Form>
                <FormItem label="分类：">
                    <TagSelect v-model="type" expandable>
                        <TagSelectOption name="type1">类别一</TagSelectOption>
                        <TagSelectOption name="type2">类别二</TagSelectOption>
                        <TagSelectOption name="type3">类别三</TagSelectOption>
                        <TagSelectOption name="type4">类别四</TagSelectOption>
                        <TagSelectOption name="type5">类别五</TagSelectOption>
                        <TagSelectOption name="type6">类别六</TagSelectOption>
                        <TagSelectOption name="type7">类别七</TagSelectOption>
                        <TagSelectOption name="type8">类别八</TagSelectOption>
                        <TagSelectOption name="type9">类别九</TagSelectOption>
                        <TagSelectOption name="type10">类别十</TagSelectOption>
                        <TagSelectOption name="type11">类别十一</TagSelectOption>
                        <TagSelectOption name="type12">类别十二</TagSelectOption>
                        <TagSelectOption name="type13">类别十三</TagSelectOption>
                        <TagSelectOption name="type14">类别十四</TagSelectOption>
                        <TagSelectOption name="type15">类别十五</TagSelectOption>
                        <TagSelectOption name="type16">类别十六</TagSelectOption>
                        <TagSelectOption name="type13">类别十三</TagSelectOption>
                        <TagSelectOption name="type14">类别十四</TagSelectOption>
                        <TagSelectOption name="type15">类别十五</TagSelectOption>
                        <TagSelectOption name="type16">类别十六</TagSelectOption>
                        <TagSelectOption name="type13">类别十三</TagSelectOption>
                        <TagSelectOption name="type14">类别十四</TagSelectOption>
                        <TagSelectOption name="type15">类别十五</TagSelectOption>
                        <TagSelectOption name="type16">类别十六</TagSelectOption>
                    </TagSelect>
                </FormItem>
                <Divider dashed />
                <FormItem label="排序：">
                    <RadioGroup v-model="order">
                        <Radio label="new">最新创建</Radio>
                        <Radio label="update">最后更新</Radio>
                    </RadioGroup>
                </FormItem>
            </Form>
        </Card>
        <app-template :app-list="appList" />
    </div>
</template>
<script>
import mixinxs from '../../../components/mixinx/index'
import appTemplate from './template';
import dataList from './data';
export default {
    mixins: [mixinxs.get('render')],
    name: '',
    props: [''],
    data() {
        return {
            apiConfig: {
                api: ['business'],
                config: {
                    getClassInfo: {
                        isPost: true,
                        dataName: 'classList',
                        apiUrl: 'getClassList'
                    },
                    getClassInfo1: {
                        isPost: true,
                        dataName: 'classList',
                        apiUrl: 'getClassList'
                    }
                }
            },
            classList: [],
            tabActiveKey: 'apps',
            type: [],
            order: 'new',
            appList: [],
            loading: false,
        };
    },
    components: { appTemplate },
    computed: {},
    beforeMount() { },
    mounted() {
        this.$render(
            Object.assign({}, this.apiConfig.config.getClassInfo, {
                parames: {},
                func: (returnData) => {
                    // console.log('混入返回的数据%o', returnData)
                }
            })
        )
        this.$async({
            getClassInfo: {
                isPost: true,
                dataName: 'classList',
                apiUrl: 'getClassList',
                isReturn: true,
                parames: {}
            },
            getClassInfo1: {
                isPost: true,
                dataName: 'classList',
                apiUrl: 'getClassList',
                isReturn: true,
                parames: {}
            }
        }, (res) => {
            console.log('async--res返回数据%o', res)
        })
        this.$asyncs({
            getClassInfo: {
                isPost: true,
                dataName: 'classList',
                apiUrl: 'getClassList',
                isReturn: true,
                parames: {},
                isFirst: true,
                transmit: ['a', 'b']
            },
            getClassInfo1: {
                isPost: true,
                dataName: 'classList',
                apiUrl: 'getClassList',
                isReturn: true,
                parames: {
                    'serf': '1'
                },
                transmit: ['a', 'b', 'c']
            }
        }, (err, result) => {
            if (err) {
                this.$Message.error(err);
            } else {
                console.log('输出结果集%o', { 'err': err, 'result': result })
            }
        })
        this.getApp();
    },
    methods: {
        getApp() {
            this.loading = true;
            setTimeout(() => {
                this.appList = dataList;
                this.loading = false;
            }, 1000);
        }
    },
    watch: {}
}
</script>
<style>
</style> */}